package com.yyplatform.admin.platform.generator.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import com.yyplatform.admin.platform.generator.model.dto.CodeGenColumnDTO;
import com.yyplatform.admin.platform.generator.model.dto.CodeGenDTO;
import com.yyplatform.admin.platform.generator.model.dto.CodeGenTableDTO;
import com.yyplatform.admin.platform.generator.model.entity.GenColumnConfigEntity;
import com.yyplatform.admin.platform.generator.model.entity.GenTableConfigEntity;
import com.yyplatform.admin.platform.generator.repository.GenColumnConfigRepository;
import com.yyplatform.admin.platform.generator.repository.GenTableConfigRepository;
import com.yyplatform.admin.platform.generator.service.CodeGenService;
import com.yyplatform.admin.infra.exception.ErrorCode;
import com.yyplatform.admin.infra.exception.ServiceException;

import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * Created on 2024-09-23
 */
@Service
@Slf4j
@AllArgsConstructor
public class CodeGenServiceImpl implements CodeGenService {

    private GenTableConfigRepository tableConfigRepository;
    private GenColumnConfigRepository columnConfigRepository;
    private ModelMapper modelMapper;
    private Configuration configuration;

    @Override
    public CodeGenDTO generatorCode(Long id) {
        GenTableConfigEntity genTableConfigEntity = tableConfigRepository.getReferenceById(id);
        List<GenColumnConfigEntity> configEntityList = columnConfigRepository.findByTableConfigId(id);

        CodeGenDTO codeGenDTO = new CodeGenDTO();

        //        codeGenDTO.setTableConfigDTO(modelMapper.map(genTableConfigEntity, TableConfigDTO.class));
        //        codeGenDTO.setColumnConfigDTOList(configEntityList.stream().map(e -> modelMapper.map(e,
        //        ColumnConfigDTO.class)).toList());


        // todo 开始生成代码
        Map<String, Object> root = new HashMap<String, Object>();

        root.put("tableDTO", toDTO(genTableConfigEntity));
        root.put("columnDTOList", toDTO(configEntityList, genTableConfigEntity));


        try {
            Template templateEntity = configuration.getTemplate("entity.ft");
            String entityCode = FreeMarkerTemplateUtils.processTemplateIntoString(templateEntity, root);
            codeGenDTO.setEntityCode(entityCode);


            Template templateRepository = configuration.getTemplate("repository.ft");
            String repositoryCode = FreeMarkerTemplateUtils.processTemplateIntoString(templateRepository, root);
            codeGenDTO.setRepositoryCode(repositoryCode);

            Template templateService = configuration.getTemplate("service.ft");
            String serviceCode = FreeMarkerTemplateUtils.processTemplateIntoString(templateService, root);
            codeGenDTO.setServiceCode(serviceCode);

            Template templateController = configuration.getTemplate("controller.ft");
            String controllerCode = FreeMarkerTemplateUtils.processTemplateIntoString(templateController, root);
            codeGenDTO.setControllerCode(controllerCode);

            Template templateServiceImpl = configuration.getTemplate("service_impl.ft");
            String serviceImplCode = FreeMarkerTemplateUtils.processTemplateIntoString(templateServiceImpl, root);
            codeGenDTO.setServiceImplCode(serviceImplCode);

            Template templateDTO = configuration.getTemplate("dto.ft");
            String dtoCode = FreeMarkerTemplateUtils.processTemplateIntoString(templateDTO, root);
            codeGenDTO.setDtoCode(dtoCode);

            Template templateformDto = configuration.getTemplate("form_dto.ft");
            String formDtoCode = FreeMarkerTemplateUtils.processTemplateIntoString(templateformDto, root);
            codeGenDTO.setDtoFormCode(formDtoCode);


            Template templateQueryDto = configuration.getTemplate("query_dto.ft");
            String queryDtoCode = FreeMarkerTemplateUtils.processTemplateIntoString(templateQueryDto, root);
            codeGenDTO.setDtoQueryCode(queryDtoCode);

            Template templateVue = configuration.getTemplate("vue.ft");
            String vueCode = FreeMarkerTemplateUtils.processTemplateIntoString(templateVue, root);
            codeGenDTO.setVueCode(vueCode);


        } catch (Exception e) {
            log.error("代码生成异常", e);
            throw ServiceException.of(ErrorCode.UNKNOW_ERROR);
        }


        return codeGenDTO;
    }

    private List<CodeGenColumnDTO> toDTO(List<GenColumnConfigEntity> configEntityList,
                                         GenTableConfigEntity genTableConfigEntity) {
        return configEntityList.stream().map(e -> modelMapper.map(e, CodeGenColumnDTO.class)).toList();
    }


    private CodeGenTableDTO toDTO(GenTableConfigEntity genTableConfigEntity) {
        CodeGenTableDTO dto = modelMapper.map(genTableConfigEntity, CodeGenTableDTO.class);

        return dto;
    }

}
